-- the local upvalues bandwagon
local select = select
local UnitClass = UnitClass
local UnitIsDead = UnitIsDead
local UnitIsGhost = UnitIsGhost
local UnitIsDeadOrGhost = UnitIsDeadOrGhost
local UnitIsPlayer = UnitIsPlayer
local UnitReaction = UnitReaction
local UnitIsConnected = UnitIsConnected
local UnitReactionColor = UnitReactionColor
local RAID_CLASS_COLORS = RAID_CLASS_COLORS
local UnitLevel = UnitLevel
local UnitIsTapped = UnitIsTapped
local UnitIstappedByPlayer = UnitIsTappedByPlayer
local UnitPowerType = UnitPowerType
local UnitClassification = UnitClassification
local UnitCreatureFamily = UnitCreatureFamily
local UnitCreatureType = UnitCreatureType
local UnitCanAttack = UnitCanAttack

local core = oUF.Jerry

local backdrop = core.backdrop
local statusbartexture = core.statusbartexture

-- colors
local powercolor = core.powercolor
local gray = core.gray
local white = core.white
local unknown = core.unknown

local auraIcon = core.auraIcon
local OnEnter, OnLeave = core.OnEnter, core.OnLeave
local getFontString = core.getFontString
local styleClicks = core.styleClicks

local function updateName(self, event, unit)
	if self.unit ~= unit then return end
	self.Name:SetText(UnitName(unit))
end

local MH = LibStub("LibMobHealth-4.0")

local function updateHealth(self, event, bar, unit, min, max)
	min, max = MH:GetUnitHealth(unit)

	if UnitIsDead(unit) then
		bar:SetValue(0)
		bar.value:SetText("Dead")
	elseif UnitIsGhost(unit) then
		bar:SetValue(0)
		bar.value:SetText("Ghost")
	elseif not UnitIsConnected(unit) then
		bar:SetValue(0)
		bar.value:SetText("Offline")
	elseif min < max then
		bar.value:SetFormattedText("|cffff8080%d|r", min - max)
	else
		bar.value:SetText(max)
	end

	local color
	if UnitIsPlayer(unit) then
		color = RAID_CLASS_COLORS[select(2, UnitClass(unit))]
	elseif UnitIsTapped(unit) and not UnitIsTappedByPlayer(unit) then
		color = gray
	else
		color = UnitReactionColor[UnitReaction(unit, "player")]
	end
	if not color then
		color = unknown
	end
	bar:SetStatusBarColor(color.r, color.g, color.b)
	bar.bg:SetTexture(color.r, color.g, color.b, .25)
end


local function updatePower(self, event, bar, unit, min, max)
	if max == 0 or UnitIsDeadOrGhost(unit) or not UnitIsConnected(unit) then
		bar:SetValue(0)
	end

	local color = powercolor(unit)
	bar:SetStatusBarColor(color.r, color.g, color.b)
	bar.bg:SetTexture(color.r, color.g, color.b, 0.25)
end

local function setStyle(settings, self, unit)
	styleClicks(self)

	-- Background
	self:SetBackdrop(backdrop)
	self:SetBackdropColor(0,0,0,1)

	-- Healthbar
	local hp = CreateFrame("StatusBar", nil, self)
	hp:SetHeight(16)
	hp:SetStatusBarTexture(statusbartexture)
	hp:SetPoint("TOPLEFT")
	hp:SetPoint("TOPRIGHT")

	-- Healthbar background
	hp.bg = hp:CreateTexture(nil, "BORDER")
	hp.bg:SetAllPoints(hp)
	hp.bg:SetTexture(.25,.25,.25)

	-- Healthbar text
	hp.value = getFontString(hp)
	hp.value:SetPoint("RIGHT", -2, -1)

	self.Health = hp
	self.OverrideUpdateHealth = updateHealth

	local icon = hp:CreateTexture(nil, "OVERLAY")
	icon:SetHeight(16)
	icon:SetWidth(16)
	icon:SetPoint("TOP", self, 0, 8)
	icon:SetTexture("Interface\\TargetingFrame\\UI-RaidTargetingIcons")
	self.RaidIcon = icon

	self.Name = getFontString(hp)
	self.Name:SetPoint("LEFT", 2, -1)
	self.UNIT_NAME_UPDATE = updateName

	-- Power Bar
	local pp = CreateFrame("StatusBar", nil, self)
	pp:SetHeight(4)
	pp:SetStatusBarTexture(statusbartexture)

	pp:SetPoint("LEFT")
	pp:SetPoint("RIGHT")
	pp:SetPoint("TOP", hp, "BOTTOM", 0, -1.35)

	local ppbg = pp:CreateTexture(nil, "BORDER")
	ppbg:SetAllPoints(pp)
	ppbg:SetTexture(.25,.25,.25)

	pp.bg = ppbg
	self.Power = pp
	self.OverrideUpdatePower = updatePower

	local buffheight = 16 -- which happens to be the oUF default
	local buffwidth = settings["initial-width"]
	buffwidth = buffwidth - (buffwidth%16) -- make sure we have exactly enough room for the buffs

	local debuffs = CreateFrame("Frame", nil, self)
	debuffs.size = buffheight
	debuffs:SetHeight(buffheight)
	debuffs:SetWidth(buffwidth)

	debuffs:SetPoint("TOPRIGHT", self, "TOPLEFT", -1.5, 0)
	debuffs.initialAnchor = "TOPRIGHT"
	debuffs["growth-y"] = "DOWN"
	debuffs["growth-x"] = "LEFT"
	debuffs.num = 40
	self.Debuffs = debuffs

	local buffs = CreateFrame("Frame", nil, self)
	buffs.size = buffheight
	buffs:SetHeight(buffheight)
	buffs:SetWidth(buffwidth)
	buffs:SetPoint("TOPLEFT", self, "BOTTOMLEFT", 0, -3)
	buffs.initialAnchor = "TOPLEFT"
	buffs["growth-y"] = "DOWN"
	buffs["growth-x"] = "RIGHT"
	buffs.num = 40
	self.Buffs = buffs

	self.PostCreateAuraIcon = auraIcon

	return self
end

local style = {
	["initial-width"] = 125,
	["initial-height"] = 21,
	setup = setStyle,
}

local tot = oUF:Spawn("targettarget", "oUF_TargetTarget", style)
tot:SetPoint("TOPRIGHT", oUF_Target, "BOTTOMRIGHT", 0, -5)

local tof = oUF:Spawn("focustarget", "oUF_Focustarget", style)
tof:SetPoint("TOPRIGHT", oUF_Focus, "BOTTOMRIGHT", 0, -5)
